package com.drakulo.games.ais.ui;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.geom.Polygon;

import com.drakulo.games.ais.core.GameData;
import com.drakulo.games.ais.core.building.Building;
import com.drakulo.games.ais.ui.component.ProgressBar;

/**
 * Helper for basic UI rendering.
 * 
 * @author Drakulo
 * 
 */
public final class UIHelper {
	/**
	 * Private constructor to force static use
	 */
	private UIHelper() {
		// Nothing there
	}

	/**
	 * Render a box with the basic background (metal texture)
	 * 
	 * @param g
	 *            - the graphic canvas
	 * @param x
	 *            - x coordinate of the top left point of the box
	 * @param y
	 *            - y coordinate of the top left point of the box
	 * @param width
	 *            - the box width
	 * @param height
	 *            - the box height
	 * @throws SlickException
	 */
	public static void drawBox(Graphics g, int x, int y, int width, int height)
			throws SlickException {
		Image bg = ImageManager.getGfx("metal_texture").getSubImage(0, 0,
				width, height);
		bg.draw(x, y);
		g.setColor(Style.BORDER_COLOR);
		g.drawRect(x, y, width, height);
	}

	public static void drawDarkBox(Graphics g, int x, int y, int width, int height) throws SlickException{
		Image bg = ImageManager.getGfx("metal_texture").getSubImage(0, 0,
				width, height);
		bg.draw(x, y, Style.BORDER_COLOR);
		g.setColor(Style.BORDER_COLOR);
		g.drawRect(x, y, width, height);
	}
	
	/**
	 * Render a black box
	 * 
	 * @param g
	 *            - the graphic canvas
	 * @param x
	 *            - x coordinate of the top left point of the box
	 * @param y
	 *            - y coordinate of the top left point of the box
	 * @param width
	 *            - the box width
	 * @param height
	 *            - the box height
	 */
	public static void drawBlackBox(Graphics g, int x, int y, int width,
			int height) {
		g.setColor(Color.black);
		g.fillRect(x, y, width, height);
		g.setColor(Style.BORDER_COLOR);
		g.drawRect(x, y, width, height);
	}

	public static void drawLeftToRightArrow(Graphics g, int x, int y, int width) {
		final int arrowWidth = 25;
		final int arrowHeight = 10;

		// The basic line
		drawHArrowLine(g, x, y, width - arrowWidth);

		// The final triangle
		Polygon triangle = new Polygon();
		triangle.addPoint(x + width - arrowWidth, y - arrowHeight);
		triangle.addPoint(x + width, y);
		triangle.addPoint(x + width - arrowWidth, y + arrowHeight);
		g.fill(triangle);
	}

	public static void drawVArrowLine(Graphics g, int x, int y, int height) {
		g.setColor(Style.ARROW_COLOR);
		g.drawLine(x - 1, y, x - 1, y + height);
		g.drawLine(x, y, x, y + height);
		g.drawLine(x + 1, y, x + 1, y + height);
	}

	public static void drawHArrowLine(Graphics g, int x, int y, int width) {
		g.setColor(Style.ARROW_COLOR);
		g.drawLine(x, y - 1, x + width, y);
		g.drawLine(x, y, x + width, y);
		g.drawLine(x, y + 1, x + width, y);
	}

	/**
	 * Create a Progress bar with static properties
	 * 
	 * @param title
	 *            The inner title
	 * @param color
	 *            The progress color
	 * @return the progress bar
	 */
	public static ProgressBar createBar(String title, Color color,
			boolean displayValues) {
		ProgressBar pb = new ProgressBar(displayValues);
		pb.setWidth(102);
		pb.setHeight(20);
		pb.setEmptyColor(Color.darkGray);
		pb.setFilledColor(color);
		pb.setTitle(FontHelper.firstToUpper(title));
		return pb;
	}

	public static Image getRoadGfx(Building road) throws SlickException {
		// Retreiving neighbors data
		Building neighbor1 = GameData.getSelectedColony().getBuildingAt(
				road.getX(), road.getY() - 1);
		Building neighbor2 = GameData.getSelectedColony().getBuildingAt(
				road.getX() + 1, road.getY());
		Building neighbor3 = GameData.getSelectedColony().getBuildingAt(
				road.getX(), road.getY() + 1);
		Building neighbor4 = GameData.getSelectedColony().getBuildingAt(
				road.getX() - 1, road.getY());

		// Beware, funky binary code ahead!
		int data = 0;
		if (neighbor1 != null) {
			data += 1;
		}
		if (neighbor2 != null) {
			data += 10;
		}
		if (neighbor3 != null) {
			data += 100;
		}
		if (neighbor4 != null) {
			data += 1000;
		}

		// Explanations:
		// ones : building at north
		// tens : building ad east
		// hundreds : building at south
		// thousands : building at west

		// It come out like this :
		// - 0001 : north
		// - 0010 : east
		// - 0011 : east + north
		// - 0100 : south
		// - 0101 : south + north
		// - 0110 : south + east
		// - 0111 : south + east + north
		// - 1000 : west
		// - 1001 : west + north
		// - 1010 : west + east
		// - 1011 : west + east + north
		// - 1100 : west + south
		// - 1101 : west + south + north
		// - 1110 : west + south + east
		// - 1111 : west + south + east + north

		// This 4 digit number is considered as a binary number/
		// Converted into integer, it gives the tile ID!
		int tileID = Integer.valueOf(String.valueOf(data), 2);

		Image image = ImageManager.getGfx("roads");
		SpriteSheet sp = new SpriteSheet(image, 32, 32);

		return sp.getSprite(tileID, 0);
	}

	/**
	 * Draws a window : black background with a metal like border
	 * 
	 * @param g
	 *            - the graphic canvas
	 * @param x
	 *            - x coordinate of the top left point of the box
	 * @param y
	 *            - y coordinate of the top left point of the box
	 * @param width
	 *            - the box width
	 * @param height
	 *            - the box height
	 * @param border
	 *            - the border size
	 * @throws SlickException
	 */
	public static void drawWindow(Graphics g, int x, int y, int w, int h,
			int border) throws SlickException {
		UIHelper.drawBox(g, x, y, w, h);
		UIHelper.drawDarkBox(g, x + border, y + border, w - 2 * border, h - 2
				* border);
	}
	
	/**
	 * Draws a window : black background with a default metal like border
	 * 
	 * @param g
	 *            - the graphic canvas
	 * @param x
	 *            - x coordinate of the top left point of the box
	 * @param y
	 *            - y coordinate of the top left point of the box
	 * @param width
	 *            - the box width
	 * @param height
	 *            - the box height
	 * @throws SlickException
	 */
	public static void drawWindow(Graphics g, int x, int y, int w, int h) throws SlickException {
		final int border = 5;
		UIHelper.drawBox(g, x, y, w, h);
		UIHelper.drawBlackBox(g, x + border, y + border, w - 2 * border, h - 2
				* border);
	}
}
